/**
 * jwt工具类
 *
 * @param null
 * @return null
 * @throws
 * @version 1.0.0
 * @author luwc
 * @time 2023/4/21 15:46:43
 */
package com.lwc.cfdns.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import com.lwc.cfdns.config.JwtConfig;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;

@EnableConfigurationProperties(JwtConfig.class)
@Component
public class JwtUtils {
    private static JwtConfig jwtConfig;

    /**
     * 存进客户端的 token 的 key 名
     */
    public static final String USER_LOGIN_TOKEN = "token";

    /**
     * 创建 TOKEN
     *
     * @param sub jwt 所面向的用户，即用户名
     * @return String
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/4/21 15:44:57
     */
    public static String createToken(String sub) {
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + jwtConfig.getExpireTime() * 1000);
        return jwtConfig.getTokenPrefix() + JWT.create()
//                .withClaim("loginPass",user.getRead_userpass()) //自定义，登录用户密码
                .withSubject(sub)
                .withExpiresAt(expireDate)
                .sign(Algorithm.HMAC512(jwtConfig.getSecret()));
    }


    /**
     * 创建 TOKEN
     *
     * @param sub jwt 所面向的用户，即用户名
     * @return String
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/4/21 15:44:57
     */
    public static String createToken(String sub, String module) {
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + jwtConfig.getExpireTime() * 1000);
        return JWT.create()
                .withClaim("module", module) //自定义，模块
                .withSubject(sub)
                .withExpiresAt(expireDate)
                .sign(Algorithm.HMAC512(jwtConfig.getSecret()));
    }

    /**
     * 验证 token
     *
     * @param token 验证的 token 值
     * @return String 用户名
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/4/21 15:46:04
     */
    public static String validateToken(String token) throws Exception {
        String sub = "";
        try {
            Verification verification = JWT.require(Algorithm.HMAC512(jwtConfig.getSecret()));
            JWTVerifier jwtVerifier = verification.build();
            // 去除 token 的前缀
            String noPrefixToken = token.replace(jwtConfig.getTokenPrefix(), "");
            DecodedJWT decodedJwt = jwtVerifier.verify(noPrefixToken);
            if (decodedJwt != null) {
                sub = decodedJwt.getSubject();
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        } catch (JWTVerificationException e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        } finally {
            return sub;
        }
    }

    /**
     * 检查 token 是否需要更新
     *
     * @param token
     * @return boolean
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/4/21 15:46:29
     */
    public static boolean isNeedUpdate(String token) throws Exception {
        // 获取 token 过期时间
        Date expiresAt = null;
        try {
            expiresAt = JWT.require(Algorithm.HMAC512(jwtConfig.getSecret()))
                    .build()
                    .verify(token.replace(jwtConfig.getTokenPrefix(), ""))
                    .getExpiresAt();
        } catch (TokenExpiredException e) {
            return true;
        } catch (Exception e) {
            throw new Exception(("token 验证失败"));
        }
        // 需要更新
        return (expiresAt.getTime() - System.currentTimeMillis()) < (jwtConfig.getExpireTime() >> 1);
    }
}
